home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / examples / porting / solar_irisgl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  8.2 KB  |  323 lines

  1. /*
  2.  * Copyright 1993, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*                solar_irisgl.c
  18.  *    solar displays a planet with a moon orbiting a sun using
  19.  *    pure IRIG GL.
  20.  * 
  21.  *    Copyright 1991, Silicon Graphics, Inc.  All Rights Reserved.
  22.  *    See ~/copyright for complete rights and liability information.
  23.  *    Author:   Technical Education Course Developers
  24.  */
  25.  
  26. #include <gl/gl.h>
  27. #include <gl/device.h>
  28. #include <gl/get.h>
  29. #include <stdio.h>
  30. #include <math.h>
  31.  
  32. /* function prototypes */
  33.  
  34. void main( int, char ** );
  35. void initialize( char * );
  36. void drawscene(short angle);
  37. void setbeachball(int stripes);
  38. void beachball(unsigned long color1, unsigned long color2);
  39.  
  40. /*         main
  41.  *    main calls initialize, then goes into a loop.  Within the loop
  42.  *    drawscene is called and passed an angle, the angle is 
  43.  *    incremented and events in the event queue are processed 
  44.  *    until user exits. 
  45.  *
  46.  *    The user can exit by pressing ESCAPE or through 
  47.  *    the window manager. 
  48.  *
  49.  *    If the LEFTMOUSE button is pressed mouse x/y input is 
  50.  *    read from the queue until the button is released.  
  51.  *    The mouse x/y input is passed to drawscene. 
  52.  */
  53.  
  54. void
  55. main( int argc, char *argv[] )
  56. {
  57.     Boolean exitflag = FALSE;
  58.     short value;
  59.     long dev;
  60.     short angle = 0;
  61.     short attached = 0; /* attached flags changes to input focus */
  62.  
  63.     if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0) {
  64.         fprintf(stderr, "This machine does not have a zbuffer\n");
  65.         exit(0);
  66.     }
  67.     initialize( argv[0] );
  68.  
  69.     while (exitflag == FALSE) {
  70.         drawscene(angle);
  71.  
  72.         /* increment angle each time scene is drawn */
  73.         if (angle < 3600)
  74.             angle = angle + 10;
  75.         else
  76.             angle = 0;
  77.  
  78.         while ( (exitflag == FALSE) && (qtest() || !attached) ) {
  79.             /* if not attached, block until there is a 
  80.              * queue entry */
  81.             dev = qread (&value);
  82.             if (dev == ESCKEY) {
  83.                 /* if the device is ESCKEY, exit program 
  84.                  * on key up */
  85.                 if (value == 0)
  86.                     exitflag = TRUE;
  87.             }
  88.             else if (dev == REDRAW) {
  89.                 /* if window needs to be redrawn, 
  90.                  * tell the system that the shape 
  91.                  * of the window may have changed,
  92.                  * then re-draw the scene */
  93.                 reshapeviewport();
  94.                 drawscene(angle);
  95.             }
  96.             else if (dev == INPUTCHANGE)
  97.                 attached = value;
  98.                 /* if cursor moves into window, value = gid
  99.                  * if cursor moves out of window, value = 0 */
  100.         }   /*  end while exitflag FALSE and (qtest or not attached) */
  101.     }   /*  end while exitflag FALSE */
  102.     exit(0);
  103. }    /*   end main()   */
  104.  
  105. /*        initialize     
  106.  *    Positions the window and specifies its future constraints.  
  107.  *    Graphics configuration is set and event queue is initialized. 
  108.  */
  109. void 
  110. initialize( char *progname )
  111. {
  112.     long gid1, xmax, ymax;
  113.     float aspect;
  114.  
  115.     xmax = getgdesc(GD_XPMAX);
  116.     ymax = getgdesc(GD_YPMAX);
  117.  
  118.     prefposition(xmax/4, xmax*3/4, ymax/4, ymax*3/4);
  119.     gid1 = winopen( progname );
  120.     minsize(xmax/10, ymax/10);
  121.     keepaspect(xmax, ymax);
  122.     winconstraints();
  123.  
  124.     doublebuffer();
  125.     RGBmode();
  126.     gconfig();
  127.  
  128.     zbuffer(TRUE);
  129.     shademodel(FLAT);
  130.  
  131.     qdevice(LEFTMOUSE);
  132.     qdevice(MIDDLEMOUSE);
  133.     qdevice(ESCKEY);
  134.     tie(LEFTMOUSE, MOUSEX, MOUSEY);
  135.  
  136.     /* separtae ModelView and Projection matrix stacks;
  137.      * both are initialized with an identity matrix.
  138.      */
  139.     mmode(MVIEWING);
  140.     aspect = (float) xmax / (float) ymax;
  141.  
  142.     /* projection commands replace projection matrix */
  143.     perspective(450, aspect, 1.0, 25.0);
  144.  
  145.     /* viewing commands premultiply the ModelView matrix */
  146.     polarview(12.0, 0, -100, 0);
  147. }    /*   end initialize()   */
  148.  
  149. /*        drawscene
  150.  *    drawscene calculates angles relative to the yearangle, 
  151.  *    and then draws sun, planet, and moon.
  152.  */
  153.  
  154. void
  155. drawscene(short yearangle)
  156. {
  157.     static long blackcol[] = { 0, 0, 0 };
  158.     static long bluecol[] = { 0, 0, 255 };
  159.     static long whitecol[] = { 255, 255, 255 };
  160.     short sunangle, dayangle, monthangle;
  161.     /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
  162.     float earthdist = 4.5, earthscale = 0.5;
  163.     float moondist = 0.9, moonscale = 0.2;
  164.  
  165.     c3i(blackcol);
  166.     /* clear color & z buffers */
  167.     czclear(getgdesc(GD_ZMIN),getgdesc(GD_ZMAX)); 
  168.     pushmatrix();
  169.     sunangle = (yearangle*365/25) % 3600;
  170.     /* sun rotates on axis every 25 days */
  171.     rotate(sunangle, 'y');
  172.     beachball(0x20C0FF, 0x200FFFF); /* colors in cpack format */
  173.     popmatrix();
  174.     pushmatrix();
  175.     rotate(yearangle, 'y');
  176.     translate(earthdist, 0.0, 0.0);
  177.     pushmatrix();
  178.     dayangle = (yearangle*50) % 3600; /* fudged so rotation shows  */
  179.     rotate(dayangle, 'y');
  180.     scale(earthscale, earthscale, earthscale);
  181.     c3i(bluecol);
  182.     beachball(0xFF0000, 0xC02000); /* earth */
  183.     popmatrix();
  184.     monthangle = (yearangle*365/28) % 3600;
  185.     rotate(monthangle, 'y');
  186.     translate (moondist, 0.0, 0.0);
  187.     scale(moonscale, moonscale, moonscale);
  188.     c3i(whitecol);
  189.     beachball(0xFFFFFF, 0xC0C0C0); /* moon */
  190.     popmatrix();
  191.  
  192.     swapbuffers();
  193. }   /*  end drawscene()  */
  194.  
  195.  
  196. /* BEACHBALL */
  197.  
  198. /* three dimensional vector */
  199. typedef float vector[3];
  200.  
  201. static vector front  = { 0.0,  0.0,  1.0 };
  202. static vector back   = { 0.0,  0.0, -1.0 };
  203. static vector top    = { 0.0,  1.0,  0.0 };
  204. static vector bottom = { 0.0, -1.0,  0.0 };
  205. static vector right  = { 1.0,  0.0,  0.0 };
  206. static vector left   = { -1.0,  0.0,  0.0 };
  207. static vector center = { 0.0,  0.0,  0.0 };
  208.  
  209. /* Number of colored stripes. Should be even to look right */
  210. #define BEACHBALL_STRIPES 12
  211.  
  212. /* Default number of polygons  making up a stripe. Should be even */
  213. #define BEACHBALL_POLYS 16
  214.  
  215. /* array of vertices making up a stripe */
  216. static vector stripe_point[BEACHBALL_POLYS + 3];
  217.  
  218. /* has the beachball been initialized */
  219. static Boolean beachball_initialized = FALSE;
  220.  
  221. /* Number of polygons making up a stripe */
  222. static int beachball_stripes;
  223.  
  224. /* Number of vertices making up a stripe */
  225. static int stripe_vertices;
  226.  
  227. /* Initialize beachball_point array to be a stripe 
  228.  * of unit radius.
  229.  */
  230. void setbeachball(int stripes)
  231. {
  232.     int i,j;
  233.     float x,y,z;             /* vertex points */
  234.     float theta,delta_theta;    /* angle from top pole to bottom pole */
  235.     float offset;         /* offset from center of stripe to vertex */
  236.     float cross_radius; /* radius of cross section at current latitude */
  237.     float cross_theta;  /* angle occupied by a stripe  */
  238.  
  239.     beachball_stripes = stripes;
  240.  
  241.     /* polys distributed by even angles from top to bottom */
  242.     delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
  243.     theta = delta_theta;
  244.  
  245.     cross_theta = 2.0*M_PI/(float)beachball_stripes;
  246.  
  247.     j = 0;
  248.  
  249.     stripe_point[j][0] = top[0];
  250.     stripe_point[j][1] = top[1];
  251.     stripe_point[j][2] = top[2];
  252.     j++;
  253.  
  254.     for (i = 0; i < BEACHBALL_POLYS; i += 2) {
  255.         cross_radius = fsin(theta);
  256.         offset = cross_radius * ftan(cross_theta/2.0);
  257.  
  258.         stripe_point[j][0] = - offset;
  259.         stripe_point[j][1] = fcos(theta);
  260.         stripe_point[j][2] = cross_radius;
  261.         j++;
  262.  
  263.         stripe_point[j][0] = offset;
  264.         stripe_point[j][1] = stripe_point[j-1][1];
  265.         stripe_point[j][2] = stripe_point[j-1][2];
  266.         j++;
  267.  
  268.         theta += delta_theta;
  269.     }
  270.  
  271.     stripe_point[j][0] = bottom[0];
  272.     stripe_point[j][1] = bottom[1];
  273.     stripe_point[j][2] = bottom[2];
  274.  
  275.     stripe_vertices = j + 1;
  276.  
  277.     beachball_initialized = TRUE;
  278. }
  279.  
  280. /*
  281.  *    Draws a canonical beachball.  The colors are cpack values 
  282.  *    when in RGBmode, colormap indices when in colormap mode.
  283.  */
  284. void beachball(unsigned long c1, unsigned long c2)
  285. {
  286.     long mode;
  287.     float angle, delta_angle;
  288.     int i,j;
  289.  
  290.     if (! beachball_initialized)
  291.         setbeachball(BEACHBALL_STRIPES);
  292.  
  293.     mode = getdisplaymode();
  294.  
  295.     angle = 0.0;
  296.     delta_angle = 360.0/(float)beachball_stripes;
  297.  
  298.     for (i = 0; i < beachball_stripes; i++) {
  299.         switch(mode) {
  300.         case DMSINGLE: case DMDOUBLE:
  301.             if ( i%2 == 0)
  302.                 color(c1);
  303.             else color(c2);
  304.             break;
  305.         case DMRGB: case DMRGBDOUBLE:
  306.             if ( i%2 == 0)
  307.                 cpack(c1);
  308.             else cpack(c2);
  309.             break;
  310.         }
  311.  
  312.         pushmatrix();
  313.         rot(angle, 'y');
  314.         angle += delta_angle;
  315.  
  316.         bgntmesh();
  317.             for (j = 0; j < stripe_vertices; j++)
  318.                 v3f(stripe_point[j]);
  319.         endtmesh();
  320.         popmatrix();
  321.     }
  322. }
  323.